package org.jeecg.modules.kuner.userrec.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;

import org.jeecg.common.util.CollectionsUtil;
import org.jeecg.common.util.PlanifoliaRedisUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.Strings;
import org.jeecg.modules.kuner.userrec.entity.UserRecBase;
import org.jeecg.modules.kuner.userrec.mapper.UserRecBaseMapper;
import org.jeecg.modules.kuner.userrec.service.IUserRecBaseService;
import org.jeecg.modules.putil.wx.WxUtil;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Optional;
import java.util.Set;

/**
 * @Description: 会员推荐码信息
 * @Author: jeecg-boot
 * @Date: 2024-08-28
 * @Version: V1.0
 */
@Slf4j
@Service
public class UserRecBaseServiceImpl extends ServiceImpl<UserRecBaseMapper, UserRecBase> implements IUserRecBaseService {

    @Resource
    private ISysUserService sysUserService;
    @Resource
    private PlanifoliaRedisUtil planifoliaRedisUtil;
    @Resource
    private WxUtil wxUtil;


    /**
     * 根据会员ID查询会员的推荐码信息，若第一次获取到信息为空则自动构建出一条推荐码信息
     *
     * @param id 会员ID
     * @return 查询到的推荐码信息
     */
    @Override
    public UserRecBase getUserRecInfo(String id) {
        SysUser sysUser = Optional.ofNullable(sysUserService.getById(id)).orElseThrow(() -> new JeecgBootException("无法找到该会员信息！"));
        UserRecBase memberRecBase = getOne(new LambdaQueryWrapper<UserRecBase>().eq(UserRecBase::getUserId, id));
        if (memberRecBase == null) {
            log.info("用户之前未创建过推荐码");
            String recCode = genMemberRecCode();
            log.info("创建成功！推荐码为:{}", recCode);
            String qcUrl = wxUtil.getMinAppQcCodeAndUpload(recCode, "pages/index/index");
            memberRecBase = new UserRecBase().setUserId(sysUser.getId()).setUserName(sysUser.getRealname()).setRecCode(recCode).setRecQcCode(qcUrl);
            save(memberRecBase);
        }
        memberRecBase.setUserName(sysUser.getRealname());
        return memberRecBase;
    }

    /**
     * 根据推荐码查询会员信息
     *
     * @param recCode 推荐码
     * @return 查询到的会员信息
     */
    @Override
    public SysUser getUserByRecCode(String recCode) {
        return this.getBaseMapper().selectUserByRecCode(recCode);
    }

    /**
     * 生成会员的推荐码，并且刷新缓存
     *
     * @return 生成出来的不可能重复的推荐码set
     */
    private synchronized String genMemberRecCode() {
        Set<String> memberAllRecCodeSet = getMemberAllRecCodeSet();
        String recCode;
        int tryTimes = 1;
        do {
            recCode = Strings.generateRecommendationCode();
            log.info("推荐码生成工具-第 {} 次生成推荐码：{}", tryTimes, recCode);
            if (tryTimes >= 10)
                throw new JeecgBootException("无法生成唯一的推荐码！，请尝试增加推荐码长度！");
            tryTimes++;
        } while (memberAllRecCodeSet.contains(recCode));
        memberAllRecCodeSet.add(recCode);
        planifoliaRedisUtil.set(CommonConstant.USER_REC_CODE_ALL, memberAllRecCodeSet);
        return recCode;
    }

    /**
     * 获取会员全部的推荐码set
     *
     * @return 会员全部的推荐码set
     */
    private Set<String> getMemberAllRecCodeSet() {
        UserRecBaseMapper baseMapper = this.getBaseMapper();
        Set<String> allRecCode = planifoliaRedisUtil.getSet(CommonConstant.USER_REC_CODE_ALL, String.class);
        if (!CollectionsUtil.isEmpty(allRecCode)) {
            return allRecCode;
        }
        Set<String> allRecCodeSet = baseMapper.selectAllRecCode();
        planifoliaRedisUtil.set(CommonConstant.USER_REC_CODE_ALL, allRecCodeSet);
        return allRecCodeSet;
    }
}
